package com.campusbackend.controller;

import com.campusbackend.entity.Result;
import com.campusbackend.entity.vo.PendingAuditUserVO;
import com.campusbackend.entity.vo.UserAuditRequestVO;
import com.campusbackend.entity.vo.UserStatisticsVO;
import com.campusbackend.entity.vo.UserManagementVO;
import com.campusbackend.entity.vo.UserSearchRequestVO;
import com.campusbackend.entity.vo.UserDetailVO;
import com.campusbackend.entity.vo.UserUpdateRequestVO;
import com.campusbackend.entity.vo.DailyUserStatisticsVO;
import com.campusbackend.service.UserAuditService;
import com.campusbackend.utils.ResultUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.*;
import java.time.format.DateTimeFormatter;

/**
 * 用户审核管理控制器
 * 
 * @author yezi
 * @since 2025-07-27
 */
@Slf4j
@RestController
@RequestMapping("/admin/user")
@Tag(name = "用户审核管理", description = "用户审核和管理相关接口")
public class UserAuditController {

    @Autowired
    private UserAuditService userAuditService;

    /**
     * 获取待审核用户列表
     * @return 待审核用户列表
     */
    @GetMapping("/pending")
    @Operation(summary = "获取待审核用户列表", description = "获取所有待审核的教师和学生")
    public Result<List<PendingAuditUserVO>> getPendingAuditUsers() {
        log.info("获取待审核用户列表请求");
        
        try {
            List<PendingAuditUserVO> users = userAuditService.getPendingAuditUsers();
            return ResultUtil.success(users);
        } catch (Exception e) {
            log.error("获取待审核用户列表异常", e);
            return ResultUtil.fail("获取待审核用户列表时发生错误");
        }
    }

    /**
     * 审核用户
     * @param auditRequest 审核请求
     * @return 审核结果
     */
    @PostMapping("/audit")
    @Operation(summary = "审核用户", description = "对用户的注册申请进行通过或驳回操作")
    public Result<String> auditUser(@Valid @RequestBody UserAuditRequestVO auditRequest) {
        log.info("用户审核请求 - userId: {}, userType: {}, auditStatus: {}", 
                 auditRequest.getUserId(), auditRequest.getUserType(), auditRequest.getAuditStatus());
        
        try {
            String result = userAuditService.auditUser(auditRequest);
            
            // 判断审核是否成功
            if (result.contains("成功")) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("用户审核异常", e);
            return ResultUtil.fail("审核过程中发生错误，请稍后重试");
        }
    }

    /**
     * 获取用户统计信息
     * @return 用户统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取用户统计信息", description = "获取用户数量与增减情况统计")
    public Result<UserStatisticsVO> getUserStatistics() {
        log.info("获取用户统计信息请求");
        
        try {
            UserStatisticsVO statistics = userAuditService.getUserStatistics();
            return ResultUtil.success(statistics);
        } catch (Exception e) {
            log.error("获取用户统计信息异常", e);
            return ResultUtil.fail("获取用户统计信息时发生错误");
        }
    }

    /**
     * 获取教师库（所有教师）
     * @return 教师列表
     */
    @GetMapping("/teachers")
    @Operation(summary = "获取教师库", description = "获取系统中所有教师数据")
    public Result<List<UserManagementVO>> getAllTeachers() {
        log.info("获取教师库请求");
        
        try {
            List<UserManagementVO> teachers = userAuditService.getAllTeachers();
            return ResultUtil.success(teachers);
        } catch (Exception e) {
            log.error("获取教师库异常", e);
            return ResultUtil.fail("获取教师库时发生错误");
        }
    }

    /**
     * 获取学生库（所有学生）
     * @return 学生列表
     */
    @GetMapping("/students")
    @Operation(summary = "获取学生库", description = "获取系统中所有学生数据")
    public Result<List<UserManagementVO>> getAllStudents() {
        log.info("获取学生库请求");
        
        try {
            List<UserManagementVO> students = userAuditService.getAllStudents();
            return ResultUtil.success(students);
        } catch (Exception e) {
            log.error("获取学生库异常", e);
            return ResultUtil.fail("获取学生库时发生错误");
        }
    }

    /**
     * 注销用户（禁用账号）
     * @param userId 用户ID
     * @param userType 用户类型：1-教师，2-学生
     * @return 注销结果
     */
    @PostMapping("/deactivate")
    @Operation(summary = "注销用户", description = "禁用现有用户库中的用户账号")
    public Result<String> deactivateUser(@RequestParam Long userId, @RequestParam Integer userType) {
        log.info("注销用户请求 - userId: {}, userType: {}", userId, userType);
        
        try {
            String result = userAuditService.deactivateUser(userId, userType);
            
            if (result.contains("成功")) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("注销用户异常", e);
            return ResultUtil.fail("注销过程中发生错误，请稍后重试");
        }
    }

    /**
     * 启用用户
     * @param userId 用户ID
     * @param userType 用户类型：1-教师，2-学生
     * @return 启用结果
     */
    @PostMapping("/activate")
    @Operation(summary = "启用用户", description = "启用被禁用的用户账号")
    public Result<String> activateUser(@RequestParam Long userId, @RequestParam Integer userType) {
        log.info("启用用户请求 - userId: {}, userType: {}", userId, userType);
        
        try {
            String result = userAuditService.activateUser(userId, userType);
            
            if (result.contains("成功")) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("启用用户异常", e);
            return ResultUtil.fail("启用过程中发生错误，请稍后重试");
        }
    }

    /**
     * 获取被驳回用户列表
     * @return 被驳回用户列表
     */
    @GetMapping("/rejected")
    @Operation(summary = "获取被驳回用户列表", description = "获取所有被驳回的教师和学生，用于导出驳回记录")
    public Result<List<PendingAuditUserVO>> getRejectedUsers() {
        log.info("获取被驳回用户列表请求");

        try {
            List<PendingAuditUserVO> users = userAuditService.getRejectedUsers();
            return ResultUtil.success(users);
        } catch (Exception e) {
            log.error("获取被驳回用户列表异常", e);
            return ResultUtil.fail("获取被驳回用户列表时发生错误");
        }
    }

    /**
     * 获取被注销用户列表
     * @return 被注销用户列表
     */
    @GetMapping("/deactivated")
    @Operation(summary = "获取被注销用户列表", description = "获取所有被注销的教师和学生，用于导出注销记录")
    public Result<List<UserManagementVO>> getDeactivatedUsers() {
        log.info("获取被注销用户列表请求");

        try {
            List<UserManagementVO> users = userAuditService.getDeactivatedUsers();
            return ResultUtil.success(users);
        } catch (Exception e) {
            log.error("获取被注销用户列表异常", e);
            return ResultUtil.fail("获取被注销用户列表时发生错误");
        }
    }

    /**
     * 搜索用户
     * @param searchRequest 搜索请求
     * @return 用户列表
     */
    @PostMapping("/search")
    @Operation(summary = "搜索用户", description = "根据姓名或学号/工号搜索用户")
    public Result<List<UserManagementVO>> searchUsers(@Valid @RequestBody UserSearchRequestVO searchRequest) {
        log.info("搜索用户请求 - keyword: {}, userType: {}", searchRequest.getKeyword(), searchRequest.getUserType());

        try {
            List<UserManagementVO> users = userAuditService.searchUsers(searchRequest);
            return ResultUtil.success(users);
        } catch (Exception e) {
            log.error("搜索用户异常", e);
            return ResultUtil.fail("搜索用户时发生错误");
        }
    }

    /**
     * 获取用户详情
     * @param loginId 登录ID（工号或学号）
     * @param userType 用户类型：1-教师，2-学生
     * @return 用户详情
     */
    @GetMapping("/detail")
    @Operation(summary = "获取用户详情", description = "根据学号/工号查看用户详细信息")
    public Result<UserDetailVO> getUserDetail(@RequestParam String loginId, @RequestParam Integer userType) {
        log.info("获取用户详情请求 - loginId: {}, userType: {}", loginId, userType);

        try {
            UserDetailVO userDetail = userAuditService.getUserDetail(loginId, userType);
            if (userDetail == null) {
                return ResultUtil.fail("用户不存在");
            }
            return ResultUtil.success(userDetail);
        } catch (Exception e) {
            log.error("获取用户详情异常", e);
            return ResultUtil.fail("获取用户详情时发生错误");
        }
    }

    /**
     * 更新用户信息
     * @param updateRequest 更新请求
     * @return 更新结果
     */
    @PostMapping("/update")
    @Operation(summary = "更新用户信息", description = "修改用户的基本信息")
    public Result<String> updateUser(@Valid @RequestBody UserUpdateRequestVO updateRequest) {
        log.info("更新用户信息请求 - userId: {}, userType: {}", updateRequest.getId(), updateRequest.getUserType());

        try {
            String result = userAuditService.updateUser(updateRequest);

            if (result.contains("成功")) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("更新用户信息异常", e);
            return ResultUtil.fail("更新过程中发生错误，请稍后重试");
        }
    }

    /**
     * 获取每日用户统计数据
     * @param days 统计天数（可选，默认7天）
     * @return 每日用户统计列表
     */
    @GetMapping("/daily-statistics")
    @Operation(summary = "获取每日用户统计数据", description = "获取最近N天的每日新增用户统计数据")
    public Result<List<DailyUserStatisticsVO>> getDailyUserStatistics(
            @RequestParam(defaultValue = "7") int days) {
        log.info("获取每日用户统计数据请求 - days: {}", days);

        try {
            // 限制查询天数范围
            if (days <= 0 || days > 30) {
                return ResultUtil.fail("查询天数必须在1-30之间");
            }

            List<DailyUserStatisticsVO> statistics = userAuditService.getDailyUserStatistics(days);
            return ResultUtil.success(statistics);
        } catch (Exception e) {
            log.error("获取每日用户统计数据异常", e);
            return ResultUtil.fail("获取每日用户统计数据时发生错误");
        }
    }

    /* ========== 数据导出接口 ========== */

    /**
     * 导出待审核用户数据
     * @return Excel文件
     */
    @GetMapping("/export/pending")
    @Operation(summary = "导出待审核用户数据", description = "导出所有待审核用户的Excel表格")
    public ResponseEntity<byte[]> exportPendingUsers() throws IOException {
        log.info("开始导出待审核用户数据");

        try {
            // 获取待审核用户数据
            List<PendingAuditUserVO> userList = userAuditService.getPendingAuditUsersForExport();
            log.info("获取到 {} 条待审核用户数据", userList.size());

            // 创建工作簿
            try (XSSFWorkbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("待审核用户");

                // 设置表头样式
                CellStyle headerStyle = createHeaderStyle(workbook);

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] headers = {"用户类型", "登录标识", "真实姓名", "手机号", "邮箱", "学院/职称", "身份证号", "注册时间"};
                createHeaderRow(headerRow, headers, headerStyle);

                // 填充数据
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                int rowNum = 1;
                for (PendingAuditUserVO user : userList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(user.getUserTypeName());
                    row.createCell(1).setCellValue(user.getLoginId());
                    row.createCell(2).setCellValue(user.getRealName());
                    row.createCell(3).setCellValue(user.getPhone() != null ? user.getPhone() : "");
                    row.createCell(4).setCellValue(user.getEmail() != null ? user.getEmail() : "");
                    row.createCell(5).setCellValue(user.getCollege() != null ? user.getCollege() : 
                                                 (user.getProfessionalTitle() != null ? user.getProfessionalTitle() : ""));
                    row.createCell(6).setCellValue(user.getIdCard() != null ? user.getIdCard() : "");
                    row.createCell(7).setCellValue(user.getCreateTime() != null ? user.getCreateTime().format(formatter) : "");
                }

                // 自动调整列宽
                for (int i = 0; i < headers.length; i++) {
                    sheet.autoSizeColumn(i);
                }

                return createExcelResponse(workbook, "待审核用户数据.xlsx");
            }
        } catch (Exception e) {
            log.error("导出待审核用户数据失败", e);
            throw new RuntimeException("导出Excel失败: " + e.getMessage());
        }
    }

    /**
     * 导出被驳回用户数据
     * @return Excel文件
     */
    @GetMapping("/export/rejected")
    @Operation(summary = "导出被驳回用户数据", description = "导出所有被驳回用户的Excel表格")
    public ResponseEntity<byte[]> exportRejectedUsers() throws IOException {
        log.info("开始导出被驳回用户数据");

        try {
            // 获取被驳回用户数据
            List<PendingAuditUserVO> userList = userAuditService.getRejectedUsersForExport();
            log.info("获取到 {} 条被驳回用户数据", userList.size());

            // 创建工作簿
            try (XSSFWorkbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("被驳回用户");

                // 设置表头样式
                CellStyle headerStyle = createHeaderStyle(workbook);

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] headers = {"用户类型", "登录标识", "真实姓名", "手机号", "邮箱", "学院/职称", "身份证号", "驳回原因", "驳回时间", "注册时间"};
                createHeaderRow(headerRow, headers, headerStyle);

                // 填充数据
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                int rowNum = 1;
                for (PendingAuditUserVO user : userList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(user.getUserTypeName());
                    row.createCell(1).setCellValue(user.getLoginId());
                    row.createCell(2).setCellValue(user.getRealName());
                    row.createCell(3).setCellValue(user.getPhone() != null ? user.getPhone() : "");
                    row.createCell(4).setCellValue(user.getEmail() != null ? user.getEmail() : "");
                    row.createCell(5).setCellValue(user.getCollege() != null ? user.getCollege() : 
                                                 (user.getProfessionalTitle() != null ? user.getProfessionalTitle() : ""));
                    row.createCell(6).setCellValue(user.getIdCard() != null ? user.getIdCard() : "");
                    row.createCell(7).setCellValue(user.getAuditReason() != null ? user.getAuditReason() : "");
                    row.createCell(8).setCellValue(user.getAuditTime() != null ? user.getAuditTime().format(formatter) : "");
                    row.createCell(9).setCellValue(user.getCreateTime() != null ? user.getCreateTime().format(formatter) : "");
                }

                // 自动调整列宽
                for (int i = 0; i < headers.length; i++) {
                    sheet.autoSizeColumn(i);
                }

                return createExcelResponse(workbook, "被驳回用户数据.xlsx");
            }
        } catch (Exception e) {
            log.error("导出被驳回用户数据失败", e);
            throw new RuntimeException("导出Excel失败: " + e.getMessage());
        }
    }

    /**
     * 导出被注销用户数据
     * @return Excel文件
     */
    @GetMapping("/export/deactivated")
    @Operation(summary = "导出被注销用户数据", description = "导出所有被注销用户的Excel表格")
    public ResponseEntity<byte[]> exportDeactivatedUsers() throws IOException {
        log.info("开始导出被注销用户数据");

        try {
            // 获取被注销用户数据
            List<UserManagementVO> userList = userAuditService.getDeactivatedUsersForExport();
            log.info("获取到 {} 条被注销用户数据", userList.size());

            // 创建工作簿
            try (XSSFWorkbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("被注销用户");

                // 设置表头样式
                CellStyle headerStyle = createHeaderStyle(workbook);

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] headers = {"用户类型", "登录标识", "真实姓名", "手机号", "邮箱", "学院/职称", "年龄", "审核状态", "账号状态", "注册时间", "更新时间"};
                createHeaderRow(headerRow, headers, headerStyle);

                // 填充数据
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                int rowNum = 1;
                for (UserManagementVO user : userList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(user.getUserTypeName());
                    row.createCell(1).setCellValue(user.getLoginId());
                    row.createCell(2).setCellValue(user.getRealName());
                    row.createCell(3).setCellValue(user.getPhone() != null ? user.getPhone() : "");
                    row.createCell(4).setCellValue(user.getEmail() != null ? user.getEmail() : "");
                    row.createCell(5).setCellValue(user.getCollege() != null ? user.getCollege() : 
                                                 (user.getProfessionalTitle() != null ? user.getProfessionalTitle() : ""));
                    row.createCell(6).setCellValue(user.getAge() != null ? user.getAge().toString() : "");
                    row.createCell(7).setCellValue(user.getAuditStatusName() != null ? user.getAuditStatusName() : "");
                    row.createCell(8).setCellValue(user.getStatusName() != null ? user.getStatusName() : "");
                    row.createCell(9).setCellValue(user.getCreateTime() != null ? user.getCreateTime().format(formatter) : "");
                    row.createCell(10).setCellValue(user.getUpdateTime() != null ? user.getUpdateTime().format(formatter) : "");
                }

                // 自动调整列宽
                for (int i = 0; i < headers.length; i++) {
                    sheet.autoSizeColumn(i);
                }

                return createExcelResponse(workbook, "被注销用户数据.xlsx");
            }
        } catch (Exception e) {
            log.error("导出被注销用户数据失败", e);
            throw new RuntimeException("导出Excel失败: " + e.getMessage());
        }
    }

    /**
     * 导出全部用户数据
     * @return Excel文件
     */
    @GetMapping("/export/all")
    @Operation(summary = "导出全部用户数据", description = "导出所有用户的Excel表格")
    public ResponseEntity<byte[]> exportAllUsers() throws IOException {
        log.info("开始导出全部用户数据");

        try {
            // 获取全部用户数据
            List<UserManagementVO> userList = userAuditService.getAllUsersForExport();
            log.info("获取到 {} 条全部用户数据", userList.size());

            // 创建工作簿
            try (XSSFWorkbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("全部用户");

                // 设置表头样式
                CellStyle headerStyle = createHeaderStyle(workbook);

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] headers = {"用户类型", "登录标识", "真实姓名", "手机号", "邮箱", "学院/职称", "年龄", "审核状态", "账号状态", "注册时间", "更新时间"};
                createHeaderRow(headerRow, headers, headerStyle);

                // 填充数据
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                int rowNum = 1;
                for (UserManagementVO user : userList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(user.getUserTypeName());
                    row.createCell(1).setCellValue(user.getLoginId());
                    row.createCell(2).setCellValue(user.getRealName());
                    row.createCell(3).setCellValue(user.getPhone() != null ? user.getPhone() : "");
                    row.createCell(4).setCellValue(user.getEmail() != null ? user.getEmail() : "");
                    row.createCell(5).setCellValue(user.getCollege() != null ? user.getCollege() : 
                                                 (user.getProfessionalTitle() != null ? user.getProfessionalTitle() : ""));
                    row.createCell(6).setCellValue(user.getAge() != null ? user.getAge().toString() : "");
                    row.createCell(7).setCellValue(user.getAuditStatusName() != null ? user.getAuditStatusName() : "");
                    row.createCell(8).setCellValue(user.getStatusName() != null ? user.getStatusName() : "");
                    row.createCell(9).setCellValue(user.getCreateTime() != null ? user.getCreateTime().format(formatter) : "");
                    row.createCell(10).setCellValue(user.getUpdateTime() != null ? user.getUpdateTime().format(formatter) : "");
                }

                // 自动调整列宽
                for (int i = 0; i < headers.length; i++) {
                    sheet.autoSizeColumn(i);
                }

                return createExcelResponse(workbook, "全部用户数据.xlsx");
            }
        } catch (Exception e) {
            log.error("导出全部用户数据失败", e);
            throw new RuntimeException("导出Excel失败: " + e.getMessage());
        }
    }

    /* ========== 辅助方法 ========== */

    /**
     * 创建表头样式
     */
    private CellStyle createHeaderStyle(XSSFWorkbook workbook) {
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);
        return headerStyle;
    }

    /**
     * 创建表头行
     */
    private void createHeaderRow(Row headerRow, String[] headers, CellStyle headerStyle) {
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
            cell.setCellStyle(headerStyle);
        }
    }

    /**
     * 创建Excel响应
     */
    private ResponseEntity<byte[]> createExcelResponse(XSSFWorkbook workbook, String filename) throws IOException {
        // 写入字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        byte[] content = outputStream.toByteArray();

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename);

        log.info("Excel文件生成成功，文件名: {}，大小: {} bytes", filename, content.length);
        return new ResponseEntity<>(content, headers, HttpStatus.OK);
    }
}
